#ifndef     __ERROR_H
#define     __ERROR_H

#include <stdint.h>

namespace utils {

namespace ec {

constexpr uint8_t Ok = 0;
constexpr uint8_t FlashFail = 0x01; // flash 读写异常
constexpr uint8_t FlashCheckFail = 0x02; // flash校验不通过
constexpr uint8_t FlashEraseFail = 0x03; // flash擦除异常
constexpr uint8_t ProtoHeadFail = 0x05; 
constexpr uint8_t ProtoSizeFail = 0x06;
constexpr uint8_t ProtoEndFail = 0x07;
constexpr uint8_t ProtoSumFail = 0x08;
constexpr uint8_t ArgParseFail = 0x09;
constexpr uint8_t Invalid = 0x0A;
constexpr uint8_t OtaIdInvalid = 0x0B;
constexpr uint8_t OtaMd5SumFail = 0x0C;
constexpr uint8_t TempFail = 0x0D; // 温度传感器异常
constexpr uint8_t Locked = 0x0E; // 电机堵转
constexpr uint8_t DrawTimeout = 0x0F; // 抽水超时, 流量计异常
constexpr uint8_t Timeout = 0x10; // 电机超时

}

namespace parts {

constexpr uint8_t Other = 0;
constexpr uint8_t Flash = 1;

}

struct Error {

    inline Error() : val(ec::Ok) {}
    inline Error(uint8_t v) : val(v) {}

    inline Error& operator=(const Error &other) {
        val = other.val;
        return *this;
    }

    inline Error& operator=(const uint8_t v) {
        val = v;
        return *this;
    }

    inline operator bool() const {
        return val != ec::Ok;
    }

    inline bool IsOk() const { return val == ec::Ok; }

    inline bool operator==(const Error &other) const {
        return(val == other.val);
    }

    inline bool operator!=(const Error &other) const {
        return (val != other.val);
    }

    uint8_t val;
};

struct Result {

    inline Result() : mod(parts::Other), val(ec::Ok) {}
    inline Result(uint8_t m) : mod(m), val(ec::Ok) {}
    inline Result(uint8_t m, uint8_t v) : mod(m), val(v) {}

    inline Result& operator=(const Result &other) {
        val = other.val;
        mod = other.mod;
        return *this;
    }
    
    inline Result& operator=(uint8_t v) {
        val = v;
        return *this;
    }

    inline operator bool() const {
        return val != ec::Ok;
    }

    inline bool IsOk() const { return val == ec::Ok; }

    inline bool operator==(const Result &other) const {
        return (mod == other.mod) && (val == other.val);
    }

    inline bool operator!=(const Result &other) const {
        return (mod != other.mod) || (val != other.val);
    }

    uint8_t mod;
    uint8_t val;
};

}


#endif
